// compile with: 
// g++ main.cpp -std=c++20 -o main
#include <iostream>
#include <string>
#include <cassert>
#define MAX_LEN 1000 // max people

struct People
{
    std::string name;
    int sex;
    int age;
    std::string phone;
    std::string address;
};

struct AddressBook
{
    People plpArray[MAX_LEN];
    int size;
};

void ShowMenu()
{
    std::cout << "***************************" << std::endl;
    std::cout << "*****  1、添加联系人  *****" << std::endl;
    std::cout << "*****  2、显示联系人  *****" << std::endl;
    std::cout << "*****  3、删除联系人  *****" << std::endl;
    std::cout << "*****  4、查找联系人  *****" << std::endl;
    std::cout << "*****  5、修改联系人  *****" << std::endl;
    std::cout << "*****  6、清空联系人  *****" << std::endl;
    std::cout << "*****  0、退出通讯录  *****" << std::endl;
    std::cout << "***************************" << std::endl;
}

void AddPeople(AddressBook* abs)
{
    if (abs->size == MAX_LEN)
    {
        std::cout << "通讯录已满，无法添加" << std::endl;
        return;
    }
    else
    {
        std::string the_name;
        std::cout << "请输入姓名(whatever string): " << std::endl;
        std::cin >> the_name;
        abs->plpArray[abs->size].name = the_name;

        std::cout << "请输入性别(输入数字 1/2): " << std::endl;
        std::cout << "[1] | 男" << std::endl;
        std::cout << "[2] | 女" << std::endl;

        int sex_id = 0;
        while (true)
        {
            std::cin >> sex_id;
            if (sex_id == 1 || sex_id == 2) // ref to above
            {
                abs->plpArray[abs->size].sex = sex_id;
                break;
            }
            std::cout << "输入有误, 请重新输入" << std::endl;
        }

        std::cout << "请输入年龄(0-150): " << std::endl;
        int the_age = 0;
        std::cin >> the_age;
        assert(the_age >= 0 && the_age < 150);
        abs->plpArray[abs->size].age = the_age;

        std::cout << "请输入联系电话(11位或7位): " << std::endl;
        std::string the_phone{ "" };
        std::cin >> the_phone;
        assert(the_phone.length() == 11 || the_phone.length() == 7);
        abs->plpArray[abs->size].phone = the_phone;

        std::cout << "请输入家庭地址(whatever string): " << std::endl;
        std::string the_address{ "" };
        std::cin >> the_address;
        abs->plpArray[abs->size].address = the_address;

        ++abs->size;

        std::cout << "本次添加成功" << std::endl;
#ifdef WIN32 // Windows
        system("pause");
        system("cls");
#endif

#ifdef __linux

#endif
    }
}

void ShowOne(AddressBook* abs)
{
    if (abs->size == 0)
        std::cout << "当前记录为空" << std::endl;
    else
    {
        for (int i = 0; i < abs->size; ++i)
        {
            std::cout << "姓名：" << abs->plpArray[i].name << "\t";
            std::cout << "性别：" << (abs->plpArray[i].sex == 1 ? "男" : "女") << "\t";
            std::cout << "年龄：" << abs->plpArray[i].age << "\t";
            std::cout << "电话：" << abs->plpArray[i].phone << "\t";
            std::cout << "住址：" << abs->plpArray[i].address << std::endl;
        }
    }

#ifdef WIN32
    system("pause");
    system("cls");
#endif
}

int HaveThis(AddressBook* abs, std::string name)
{
    for (int i = 0; i < abs->size; ++i)
    {
        if (abs->plpArray[i].name == name)
        {
            return i;
        }
    }

    return -1;
}

void DeleteOne(AddressBook* abs)
{
    std::cout << "请输入您要删除的联系人" << std::endl;
    std::string name;
    std::cin >> name;

    int ret = HaveThis(abs, name);
    if (ret != -1)
    {
        for (int i = ret; i < abs->size; ++i)
            abs->plpArray[i] = abs->plpArray[i + 1];
        abs->size--;
        std::cout << "本次删除成功" << std::endl;
    }
    else
        std::cout << "查无此人" << std::endl;
#ifdef WIN32
    system("pause");
    system("cls");
#endif
}

void FindOne(AddressBook* abs)
{
    std::cout << "请输入您要查找的联系人" << std::endl;
    std::string name;
    std::cin >> name;

    int ret = HaveThis(abs, name);
    if (ret != -1)
    {
        std::cout << "姓名：" << abs->plpArray[ret].name << "\t";
        std::cout << "性别：" << abs->plpArray[ret].sex << "\t";
        std::cout << "年龄：" << abs->plpArray[ret].age << "\t";
        std::cout << "电话：" << abs->plpArray[ret].phone << "\t";
        std::cout << "住址：" << abs->plpArray[ret].address << std::endl;
    }
    else
        std::cout << "查无此人" << std::endl;
#ifdef WIN32
    system("pause");
    system("cls");
#endif
}

void ModifyOne(AddressBook* abs)
{
    std::cout << "请输入要修改的联系人姓名" << std::endl;
    std::string name;
    std::cin >> name;
    int ret = HaveThis(abs, name);
    if (ret != -1)
    {
        // 姓名
        std::string name;
        std::cout << "请输入姓名：" << std::endl;
        std::cin >> name;
        abs->plpArray[ret].name = name;

        std::cout << "请输入性别：" << std::endl;
        std::cout << "1 -- 男" << std::endl;
        std::cout << "2 -- 女" << std::endl;

        // 性别
        int sex = 0;
        while (true)
        {
            std::cin >> sex;
            if (sex == 1 || sex == 2)
            {
                abs->plpArray[ret].sex = sex;
                break;
            }
            std::cout << "输入有误，请重新输入";
        }

        // 年龄
        std::cout << "请输入年龄：" << std::endl;
        int age = 0;
        std::cin >> age;
        abs->plpArray[ret].age = age;

        // 联系电话
        std::cout << "请输入联系电话：" << std::endl;
        std::string phone = "";
        std::cin >> phone;
        abs->plpArray[ret].phone = phone;

        // 家庭住址
        std::cout << "请输入家庭住址：" << std::endl;
        std::string address;
        std::cin >> address;
        abs->plpArray[ret].address = address;

        std::cout << "修改成功" << std::endl;
    }
    else
    {
        std::cout << "查无此人" << std::endl;
    }
#ifdef WIN32
    system("pause");
    system("cls");
#endif
}

void KickOutAll(AddressBook* abs)
{
    abs->size = 0;
    abs = nullptr;
#ifdef WIN32
    system("pause");
    system("cls");
#endif
}
int main(int argc, char const* argv[])
{
    // 创建通讯录
    AddressBook abs;
    // 初始化通讯录中人数
    abs.size = 0;
    int select = 0;

    while (true)
    {
        ShowMenu();

        std::cin >> select;

        switch (select)
        {
        case 1: // 添加联系人
            AddPeople(&abs);
            break;
        case 2: // 显示联系人
            ShowOne(&abs);
            break;
        case 3: // 删除联系人
            DeleteOne(&abs);
            break;
        case 4: // 查找联系人
            FindOne(&abs);
            break;
        case 5: // 修改联系人
            ModifyOne(&abs);
            break;
        case 6: // 清空联系人
            KickOutAll(&abs);
            break;
        case 0: // 退出通讯录
            std::cout << "欢迎下次使用" << std::endl;
#ifdef WIN32
            system("pause");
#endif
            return 0;
            break;
        default:
            break;
        }
    }
#ifdef WIN32
    system("pause");
#endif
    return 0;
}
